using Cordyceps.Micro.AuthServer.Dimain.Models;
using Cordyceps.Micro.AuthServer.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Models;
using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants;

namespace Cordyceps.Micro.AuthServer;

public class Program
{
    public static async Task Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        builder.Services.AddConnections();
        builder.Services.AddRazorPages();


        // 添加数据库上下文
        builder.Services.AddDbContext<AuthDbContext>(options =>
        {
            options.UseNpgsql(builder.Configuration.GetConnectionString("Default"));
            // 注册OpenIddict所需的实体集。
            options
                .UseOpenIddict<CordycepsOpenIddictApplications, CordycepsOpenIddictAuthorizations,
                    CordycepsOpenIddictScopes, CordycepsOpenIddictTokens, Guid>();
        });


        builder.Services.AddIdentity<CordycepsIdentityUser, CordycepsIdentityRole>()
            .AddEntityFrameworkStores<AuthDbContext>()
            .AddApiEndpoints(); ;
        //.AddDefaultUI()
        //.AddDefaultTokenProviders();


        // 集成OpenIddict服务
        builder.Services.AddOpenIddict()
            .AddCore(options =>
            {
                options.UseEntityFrameworkCore()
                    .UseDbContext<AuthDbContext>()
                    .ReplaceDefaultEntities<CordycepsOpenIddictApplications, CordycepsOpenIddictAuthorizations,
                        CordycepsOpenIddictScopes, CordycepsOpenIddictTokens, Guid>();
                ;
            })
            //生成token
            .AddServer(options =>
            {
                var IsEnv = builder.Environment.IsDevelopment();

                // 启用授权码、密码、刷新令牌等流程
                options.SetTokenEndpointUris("/connect/token");
                //.SetAuthorizationEndpointUris("/connect/authorize")
                //.SetAuthorizationEndpointUris("/connect/logout")

                options.AllowPasswordFlow()
                    .AllowClientCredentialsFlow();

                options.AcceptAnonymousClients();
                options.SetAccessTokenLifetime(TimeSpan.FromHours(1));
                options.SetRefreshTokenLifetime(TimeSpan.FromDays(7));

                options.AddEphemeralEncryptionKey()
                    .AddEphemeralSigningKey();

                options.DisableAccessTokenEncryption();


                options.RegisterScopes(
                    //OpenIddictConstants.Scopes.OpenId,
                    //OpenIddictConstants.Scopes.Profile,
                    //OpenIddictConstants.Scopes.Roles,
                    //OpenIddictConstants.Scopes.OfflineAccess,
                    "api",
                    "orderverservice"
                );


                options.UseAspNetCore()
                    .EnableAuthorizationEndpointPassthrough()
                    .EnableTokenEndpointPassthrough();
            })
            // 验证token
            .AddValidation(options =>
            {
                options.UseLocalServer();
                options.UseAspNetCore();
            });

        builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);
        //builder.Services.AddAuthorization();


        builder.Services.AddTransient<AuthServer>();



        builder.Services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo
            {
                Title = "Cordyceps.Micro.AuthServer API",
                Version = "v1"
            });
        });


        var app = builder.Build();


        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();


        #region 【注释】

        // 初始化数据库和 OpenIddict
        //await InitializeAsync(app.Services);

        //// 自定义 Token Endpoint（简化登录逻辑）
        //app.MapPost("/connect/token", async (HttpContext context) =>
        //{
        //    var request = context.Request.Form;

        //    if (request["grant_type"] != "password")
        //        return Results.BadRequest(new { error = "unsupported_grant_type" });

        //    if (request["username"] != "admin" || request["password"] != "password")
        //    {
        //        return Results.BadRequest(new { error = "invalid_grant", error_description = "Invalid credentials." });
        //    }

        //    // ✅ 修复：使用 OpenIddictConstants.Claims.Subject ("sub")
        //    var claims = new List<Claim>
        //    {
        //        new(OpenIddictConstants.Claims.Subject, "admin"),      // ← 必须！
        //        new(OpenIddictConstants.Claims.Name, "Admin User"),
        //        new(OpenIddictConstants.Claims.Email, "admin@example.com")
        //    };

        //    var identity = new ClaimsIdentity(claims, "password");
        //    var principal = new ClaimsPrincipal(identity);

        //    // 处理 scopes
        //    var scopeValue = request["scope"];
        //    var scopes = string.IsNullOrWhiteSpace(scopeValue)
        //        ? Array.Empty<string>()
        //        : scopeValue.ToString().Split(' ', StringSplitOptions.RemoveEmptyEntries);

        //    var validScopes = scopes.Where(s =>
        //        s == Scopes.Profile ||
        //        s == Scopes.Email ||
        //        s == Scopes.OfflineAccess
        //    ).ToArray();

        //    principal.SetScopes(validScopes);

        //    // ✅ 现在可以安全调用 SignInAsync
        //    await context.SignInAsync(
        //        scheme: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
        //        principal: principal,
        //        properties: new AuthenticationProperties());

        //    return Results.Empty; // OpenIddict 会自动写入响应
        //});

        #endregion

        // 开发环境启用 Swagger 中间件
        if (app.Environment.IsDevelopment())
        {
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "Cordyceps.Micro.AuthServer V1");
                c.RoutePrefix = "swagger"; // 可设为空 "" 来让根路径完全由重定向控制
            });
        }

        app.MapControllers();
        app.MapRazorPages();

        //app.MapGroup("api/identity")
        //   .WithTags("Identity")
        //   .MapIdentityApi<CordycepsIdentityUser>();

        await app.RunAsync();
    }


    // 初始化方法（仅用于演示，生产环境应通过 DbMigrator 或种子数据管理）
    protected static async Task InitializeAsync(IServiceProvider serviceProvider)
    {
        using var scope = serviceProvider.CreateScope();
        var context = scope.ServiceProvider.GetRequiredService<AuthDbContext>();
        await context.Database.EnsureCreatedAsync();

        var manager = scope.ServiceProvider.GetRequiredService<IOpenIddictApplicationManager>();


        if (await manager.FindByClientIdAsync("my_client") == null)
            await manager.CreateAsync(new OpenIddictApplicationDescriptor
            {
                ClientId = "my_client",
                ClientSecret = "my_secret",
                DisplayName = "My App",
                Permissions =
                {
                    Permissions.Endpoints.Token,
                    Permissions.GrantTypes.Password,
                    Permissions.GrantTypes.RefreshToken,
                    Permissions.Prefixes.Scope + Scopes.Profile,
                    Permissions.Prefixes.Scope + Scopes.Email
                }
            });
    }
}